//
//  main.m
//  Demo0027
//
//  Created by zTercel on 13-3-9.
//  Copyright (c) 2013年 zTercel. All rights reserved.
//

#import <Foundation/Foundation.h>

// AddressCard
//-----------------------------------------------------------
@interface AddressCard : NSObject<NSCoding>
@property(nonatomic, copy) NSString*    name;
@property(nonatomic, copy) NSString*    phone;
@property(nonatomic, copy) NSString*    email;

-(id) init: (NSString*)_name phoneNumber: (NSString*)_phone eMail: (NSString*)_email;
-(id) assignCard: (NSString*)_name phoneNumber: (NSString*)_phone eMail: (NSString*)_email;
-(id) initWithCoder:(NSCoder *)aDecoder;
-(void) encodeWithCoder:(NSCoder *)aCoder;

@end

@implementation AddressCard
@synthesize name;
@synthesize phone;
@synthesize email;

-(id) init: (NSString*)_name phoneNumber: (NSString*)_phone eMail: (NSString*)_email
{
    if (self = [super init])
    {
        self = [self assignCard:_name phoneNumber:_phone eMail:_email];
    }
    return self;
}

-(id) assignCard: (NSString*)_name phoneNumber: (NSString*)_phone eMail: (NSString*)_email;
{
    [self setName:_name];
    [self setPhone:_phone];
    [self setEmail:_email];
    
    return self;
}

-(void) encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:name forKey:@"name"];
    [aCoder encodeObject:phone forKey:@"phone"];
    [aCoder encodeObject:email forKey:@"email"];
}

-(id) initWithCoder:(NSCoder *)aDecoder
{
    name    = [aDecoder decodeObjectForKey:@"name"];
    phone   = [aDecoder decodeObjectForKey:@"phone"];
    email   = [aDecoder decodeObjectForKey:@"email"];

    return self;
}

@end

// AddressBook 
//-----------------------------------------------------------
@interface AddressBook : NSObject<NSCoding>

@property(nonatomic, copy) NSMutableDictionary* addressCardList;

-(id) init;
-(id) initWithAddress:(NSString*)_name phoneNumber: (NSString*)_phone eMail: (NSString*)_email;
-(void) setAddress:(NSString*)_name phoneNumber: (NSString*)_phone eMail: (NSString*)_email;
-(void) setAddressCard: (AddressCard*) card;
-(id) initWithCoder:(NSCoder *)aDecoder;
-(void) encodeWithCoder:(NSCoder *)aCoder;
@end

@implementation AddressBook

@synthesize addressCardList;

-(id) init
{
    if (self = [super init])
    {
        addressCardList = [NSMutableDictionary dictionaryWithCapacity:10];
    }
    return self;
}

-(id) initWithAddress:(NSString*)_name phoneNumber: (NSString*)_phone eMail: (NSString*)_email;
{
    if ([self init])
    {
        [self setAddress:_name phoneNumber:_phone eMail:_email];
    }
    
    return self;
}

-(void) setAddress: (NSString*)_name phoneNumber: (NSString*)_phone eMail: (NSString*)_email
{
    AddressCard* card = [[AddressCard alloc]init:_name phoneNumber:_phone eMail:_email];
    [addressCardList setObject:card forKey:_name];
}

-(void) setAddressCard: (AddressCard*) card
{
    [addressCardList setObject:card forKey:[card name]];
}

-(id) initWithCoder:(NSCoder *)aDecoder
{
    if ([self init])
    {
        addressCardList = [aDecoder decodeObjectForKey:@"addressBook"];
    }
    
    return self;
}

-(void) encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:addressCardList forKey:@"addressBook"];
}

-(void) print
{
    int index = 1;
    NSMutableString* description = [NSMutableString stringWithFormat:@"\nAddressBook Contain card count: %lu\n", [addressCardList count]];
    [description appendFormat:@"%-10s %-20s %-20s %-20s\n", "id", "name", "phone", "email"];
    [description appendString:@"----------------------------------------------------------------------------\n"];
    for (NSString* key in addressCardList) {
        AddressCard* card = [addressCardList objectForKey:key];
        [description appendFormat:@"%-10u %-20s %-20s %-20s\n", index++, [[card name] UTF8String], [[card phone] UTF8String], [[card email] UTF8String]];
    }
    [description appendString:@"----------------------------------------------------------------------------\n"];
    NSLog(@"%@", description);
}

@end

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        {
            AddressBook* book   = [[AddressBook alloc]init];
            
            AddressCard* card1  = [[AddressCard alloc]init:@"hanMeiMei" phoneNumber:@"132-1938-1284" eMail:@"haMeiMei@icloud.com"];
            AddressCard* card2  = [[AddressCard alloc]init:@"MaLiLi" phoneNumber:@"135-0238-1134" eMail:@"MaLiLi@icloud.com"];
            AddressCard* card3  = [[AddressCard alloc]init:@"LiLei" phoneNumber:@"159-1132-1235" eMail:@"LiLei@icloud.com"];
        
            [book setAddressCard:card1];
            [book setAddressCard:card2];
            [book setAddressCard:card3];
            [book setAddress:@"ztercel" phoneNumber:@"186-8878-6625" eMail:@"ztercel@icloud.com"];
            [book print];
            
            if ([NSKeyedArchiver archiveRootObject:book toFile:@"addressBook.data"])
            {
                NSLog(@"saved addressbook to file using NSKeyedArchiver");
            }
            
            NSMutableData* dataArea     = [NSMutableData data];
            NSKeyedArchiver* archiver   = [[NSKeyedArchiver alloc]initForWritingWithMutableData:dataArea];
            [archiver encodeObject:book forKey:@"addressBook"];
            [archiver finishEncoding];
            if ([dataArea writeToFile:@"addressbook.package" atomically:YES])
            {
                NSLog(@"saved addressbook to file using data buffer");
            };
        }
        
        {
            AddressBook* book = [NSKeyedUnarchiver unarchiveObjectWithFile:@"addressBook.data"];
            [book print];
            
            NSMutableData* data = [NSMutableData dataWithContentsOfFile:@"addressbook.package"];
            NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
            AddressBook* book1 = [unarchiver decodeObjectForKey:@"addressBook"];
            [unarchiver finishDecoding];
            [book1 print];
            
        }
    }
    return 0;
}

